//
// Created by LONG on 2020/10/17.
//

#include "../include/o5g3gppTypes.h"

#define PLMN_ID_DIGIT1(x) (((x) / 100) % 10)
#define PLMN_ID_DIGIT2(x) (((x) / 10) % 10)
#define PLMN_ID_DIGIT3(x) ((x) % 10)

uint16_t O5G_PlmnId_Mcc(S_O5gPlmnId *pPlmnId)
{
    return pPlmnId->mcc1 * 100 + pPlmnId->mcc2 * 10 + pPlmnId->mcc3;
}

uint16_t O5G_PlmnId_Mnc(S_O5gPlmnId *pPlmnId)
{
    return pPlmnId->mnc1 == 0xf ? pPlmnId->mnc2 * 10 + pPlmnId->mnc3 :
           pPlmnId->mnc1 * 100 + pPlmnId->mnc2 * 10 + pPlmnId->mnc3;
}

uint16_t O5G_PlmnId_MncLen(S_O5gPlmnId *pPlmnId)
{
    return pPlmnId->mnc1 == 0xf ? 2 : 3;
}

void O5G_PlmnId_Build(S_O5gPlmnId *pPlmnId, uint16_t mcc, uint16_t mnc, uint16_t mncLen)
{
    pPlmnId->mcc1 = PLMN_ID_DIGIT1(mcc);
    pPlmnId->mcc2 = PLMN_ID_DIGIT2(mcc);
    pPlmnId->mcc3 = PLMN_ID_DIGIT3(mcc);
    if (mncLen == 2)
    {
        pPlmnId->mnc1 = 0xf;
    }
    else
    {
        pPlmnId->mnc1 = PLMN_ID_DIGIT1(mnc);
    }
    pPlmnId->mnc2 = PLMN_ID_DIGIT2(mnc);
    pPlmnId->mnc3 = PLMN_ID_DIGIT3(mnc);
}

void O5G_SfnSlot_Add(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint16_t n)
{
    uint32_t tmp;

    tmp = (*sfn) * slotNum + (*slot) + n;
    *slot = tmp % slotNum;
    *sfn = (tmp / slotNum) % 1024;
}

void O5G_SfnSlot_Sub(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint16_t n)
{
    uint32_t tmp;

    tmp = ((*sfn) + 1024) * slotNum + (*slot) - n;
    *slot = tmp % slotNum;
    *sfn = (tmp / slotNum) % 1024;
}

void O5G_SfnSlot_ToU32(uint16_t sfn, uint16_t slot, uint16_t slotNum, uint32_t *sfnSlot)
{
    *sfnSlot = ((uint32_t)sfn * slotNum) + slot;
}

void O5G_SfnSlot_FromU32(uint16_t *sfn, uint16_t *slot, uint16_t slotNum, uint32_t sfnSlot)
{
    *slot = sfnSlot % slotNum;
    *sfn = (sfnSlot / slotNum) % 1024;
}

